home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / blat11.zip / BLAT.CPP < prev    next >
C/C++ Source or Header  |  1994-12-08  |  21KB  |  784 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <iostream.h>
  5. /* generic socket DLL support */
  6. #include "gensock.h"
  7.  
  8. #ifdef WIN32         
  9.   #define __far far
  10.   #define huge far
  11.   #define __near near
  12. #endif               
  13.  
  14. #define MAXOUTLINE 255
  15.  
  16. HANDLE    gensock_lib = 0;
  17.  
  18. int (FAR PASCAL *pgensock_connect) (char FAR * hostname, char FAR * service, socktag FAR * pst);
  19. int (FAR PASCAL *pgensock_getchar) (socktag st, int wait, char FAR * ch);
  20. int (FAR PASCAL *pgensock_put_data) (socktag st, char FAR * data, unsigned long length);
  21. int (FAR PASCAL *pgensock_close) (socktag st);
  22. int (FAR PASCAL *pgensock_gethostname) (char FAR * name, int namelen);
  23. int (FAR PASCAL *pgensock_put_data_buffered) (socktag st, char FAR * data, unsigned long length);
  24. int (FAR PASCAL *pgensock_put_data_flush) (socktag st);
  25.  
  26.  
  27. socktag SMTPSock;
  28. #define SERVER_SIZE    128     // #defines (bleah!) from Beverly Brown "beverly@datacube.com"
  29. #define SENDER_SIZE    128
  30. char SMTPHost[SERVER_SIZE];
  31. char Sender[SENDER_SIZE];
  32. char *Recipients;
  33. char my_hostname[1024];
  34. char *destination="";
  35. char *cc_list="";
  36. char *loginname="";
  37. char *senderid="";
  38. char *subject="";
  39.  
  40. char *usage[]= {
  41. "Blat v1.1: WinNT console utility to mail a file to a user via SMTP",
  42. "",
  43. "syntax:",
  44. "Blat <filename> [-s <subject>] -t <recipient> -f <address> [-i <address>]",
  45. "Blat -SMTP <server address>",
  46. "Blat -h",
  47. "",
  48. "-SMTP <server address> <senders address>: set's the address of the SMTP server to be used",
  49. "",
  50. "<filename>: the file with the message body",
  51. "-s <subject>: the (optional) subject line",
  52. "-t <recipient>: the recipient's address",
  53. "-c <recipient>: the carbon copy recipient's address",
  54. "-f <sender>: the sender's address (must be known to the SMTP server)",
  55. "-i <address>: a 'From:' address, not necessarily known to the SMTP server.",
  56. "-h: displays this help.",
  57. "",
  58. "Note that if the '-i' option is used, <sender> is included in 'Reply-to:'",
  59. "and 'Sender:' fields in the header of the message."
  60. };
  61. const NMLINES=19;
  62.  
  63. void
  64. gensock_error (char * function, int retval)
  65. {
  66.   cout << "error " << retval << " in function '" << function;
  67. }
  68.  
  69. // loads the GENSOCK DLL file
  70. int load_gensock()
  71. {
  72.   if( (gensock_lib = LoadLibrary("gensock.dll")) == NULL )
  73.   {
  74.     cout << "Couldn't load 'GENSOCK.DLL'\n";
  75.     return -1;
  76.   }
  77.  
  78.   if( 
  79.      ( pgensock_connect = 
  80.       (  int (FAR PASCAL *)(char FAR *, char FAR *, socktag FAR *) )
  81.       GetProcAddress(gensock_lib, "gensock_connect")
  82.      ) == NULL
  83.     )
  84.   {
  85.     cout << "couldn't getprocaddress for gensock_connect\n";
  86.     return -1;
  87.   }
  88.  
  89.   if (
  90.       ( pgensock_getchar =
  91.        ( int (FAR PASCAL *) (socktag, int, char FAR *) )
  92.        GetProcAddress(gensock_lib, "gensock_getchar")
  93.       ) == NULL
  94.      )
  95.   {
  96.     cout << "couldn't getprocaddress for gensock_getchar\n";
  97.     return -1;
  98.   }
  99.  
  100.   if(
  101.      ( pgensock_put_data =
  102.        ( int (FAR PASCAL *) (socktag, char FAR *, unsigned long) )
  103.        GetProcAddress(gensock_lib, "gensock_put_data")
  104.      ) == NULL
  105.     )
  106.   {
  107.     cout << "couldn't getprocaddress for gensock_put_data\n";
  108.     return -1;
  109.   }
  110.  
  111.   if(
  112.      ( pgensock_close =
  113.        (int (FAR PASCAL *) (socktag) )
  114.        GetProcAddress(gensock_lib, "gensock_close")
  115.      ) == NULL
  116.     )
  117.   {
  118.     cout << "couldn't getprocaddress for gensock_close\n";
  119.     return -1;
  120.   }
  121.  
  122.   if(
  123.      ( pgensock_gethostname =
  124.        (int (FAR PASCAL *) (char FAR *, int) )       
  125.        GetProcAddress(gensock_lib, "gensock_gethostname")
  126.      ) == NULL
  127.     )
  128.   {
  129.     cout << "couldn't getprocaddress for gensock_gethostname\n";
  130.     return -1;
  131.   }
  132.  
  133.   if(
  134.      ( pgensock_put_data_buffered =
  135.        ( int (FAR PASCAL *) (socktag, char FAR *, unsigned long) )
  136.        GetProcAddress(gensock_lib, "gensock_put_data_buffered")
  137.      ) == NULL
  138.     )
  139.   {
  140.     cout << "couldn't getprocaddress for gensock_put_data_buffered\n";
  141.     return -1;
  142.   }
  143.  
  144.   if(
  145.      ( pgensock_put_data_flush =
  146.        ( int (FAR PASCAL *) (socktag) )
  147.        GetProcAddress(gensock_lib, "gensock_put_data_flush")
  148.      ) == NULL
  149.     )
  150.   {
  151.     cout << "couldn't getprocaddress for gensock_put_data_flush\n";
  152.     return -1;
  153.   }
  154.  
  155.   return 0;
  156. }
  157.  
  158. int open_smtp_socket( void )
  159. {
  160.   int retval;
  161.  
  162.   /* load the library if it's not loaded */
  163. //  if (!gensock_lib)
  164.     if ( ( retval = load_gensock() ) ) return ( retval );
  165.  
  166.   if ( (retval = (*pgensock_connect) ((LPSTR) SMTPHost,
  167.                      (LPSTR)"smtp",
  168.                      &SMTPSock)))
  169.   {
  170.     if (retval == ERR_CANT_RESOLVE_SERVICE)
  171.     {
  172.      if ((retval = (*pgensock_connect) ((LPSTR)SMTPHost,
  173.                      (LPSTR)"25",
  174.                      &SMTPSock)))
  175.      {
  176.        gensock_error ("gensock_connect", retval);
  177.        return -1;
  178.      }
  179.     }
  180.   // error other than can't resolve service 
  181.     else
  182.     {
  183.      gensock_error ("gensock_connect", retval);
  184.      return -1;
  185.     }
  186.   }
  187.  
  188.   // we wait to do this until here because WINSOCK is
  189.   // guaranteed to be already initialized at this point.
  190.  
  191.   // get the local hostname (needed by SMTP) 
  192.   if ((retval = (*pgensock_gethostname) (my_hostname, sizeof(my_hostname))))
  193.   {
  194.     gensock_error ("gensock_gethostname", retval);
  195.     return -1;
  196.   }
  197. //  strcpy( my_hostname, "pcfchb.dbs.aber.ac.uk");
  198.   return 0;
  199. }
  200.  
  201.  
  202. int close_smtp_socket( void )
  203. {
  204.   int retval;
  205.  
  206.   if( (retval = (*pgensock_close) (SMTPSock)) )
  207.   {
  208.     gensock_error ("gensock_close", retval);
  209.     return -1;
  210.   }
  211.   FreeLibrary( gensock_lib );
  212.   return (0);
  213. }
  214.  
  215. int get_smtp_line( void )
  216. {
  217.   char ch = '.';
  218.   char in_data [MAXOUTLINE];
  219.   char * index;
  220.   int retval = 0;
  221.  
  222.   index = in_data;
  223.  
  224.   while (ch != '\n')
  225.   {
  226.    if( (retval = (*pgensock_getchar) (SMTPSock, 0, &ch) ) )
  227.    {
  228.       gensock_error ("gensock_getchar", retval);
  229.       return -1;
  230.     }
  231.     else
  232.     {
  233.       *index = ch;
  234.       index++;
  235.     }
  236.   }
  237.  
  238.   /* this is to support multi-line responses, common with */
  239.   /* servers that speak ESMTP */
  240.  
  241.   /* I know, I know, it's a hack 8^) */
  242.   if( in_data[3] == '-' ) return( get_smtp_line() );
  243.   else return atoi(in_data);
  244. }
  245.  
  246. int put_smtp_line( socktag sock, char far * line, unsigned int nchars )
  247. {
  248.   int retval;
  249.  
  250.   if( (retval = (*pgensock_put_data) (sock, line, (unsigned long) nchars)))
  251.   {
  252.     gensock_error ("gensock_put_data", retval);
  253.     return -1;
  254.   }
  255.   return (0);
  256. }
  257.  
  258. int putline_internal (socktag sock, char * line, unsigned int nchars)
  259. {
  260.   int retval;
  261.  
  262.   if ((retval =
  263.        (*pgensock_put_data) (sock,
  264.                 (char FAR *) line,
  265.                 (unsigned long) nchars)))
  266.   {
  267.     switch (retval)
  268.     {
  269.      case ERR_NOT_CONNECTED:
  270.       gensock_error( "SMTP server has closed the connection", retval );
  271.       break;
  272.  
  273.      default:
  274.       gensock_error ("gensock_put_data", retval);
  275.     }
  276.     return -1;
  277.   }
  278.   return (0);
  279. }
  280.  
  281. void smtp_error (char * message)
  282. {
  283.   cout << message << "\n";
  284.   put_smtp_line (SMTPSock, "QUIT\r\n", 6);
  285.   close_smtp_socket();
  286. }
  287.  
  288.  
  289. // 'destination' is the address the message is to be sent to
  290. // 'message' is a pointer to a null-terminated 'string' containing the 
  291. // entire text of the message. 
  292.  
  293. int prepare_smtp_message(char * MailAddress, char * destination)
  294. {
  295.   char out_data[MAXOUTLINE];
  296.   char str[1024];
  297.   char *ptr;
  298.   int len, startLen;
  299.  
  300.   if ( open_smtp_socket() ) return -1;
  301.  
  302.   if ( get_smtp_line() != 220 )
  303.   {
  304.     smtp_error ("SMTP server error");
  305.     return(-1);
  306.   }
  307.  
  308.   sprintf( out_data, "HELO %s\r\n", my_hostname );
  309.   put_smtp_line( SMTPSock, out_data, strlen (out_data) );
  310.  
  311.   if ( get_smtp_line() != 250 )
  312.   {
  313.     smtp_error ("SMTP server error");
  314.     return -1;
  315.   }
  316.  
  317.   sprintf (out_data, "MAIL From:<%s>\r\n", loginname);
  318.   put_smtp_line( SMTPSock, out_data, strlen (out_data) );
  319.  
  320.   if (get_smtp_line() != 250)
  321.   {
  322.     smtp_error ("The mail server doesn't like the sender name,\nhave you set your mail address correctly?");
  323.     return -1;
  324.   }
  325.  
  326.   // do a series of RCPT lines for each name in address line
  327.   for (ptr = destination; *ptr; ptr += len + 1)
  328.   {
  329.     // if there's only one token left, then len will = startLen,
  330.     // and we'll iterate once only
  331.     startLen = strlen (ptr);
  332.     if ((len = strcspn (ptr, " ,\n\t\r")) != startLen)
  333.     {
  334.       ptr[len] = '\0';            // replace delim with NULL char
  335.       while (strchr (" ,\n\t\r", ptr[len+1]))    // eat white space
  336.         ptr[len++] = '\0';
  337.     }
  338.  
  339.     sprintf (out_data, "RCPT To: <%s>\r\n", ptr);
  340.     putline_internal( SMTPSock, out_data, strlen (out_data) );
  341.  
  342.     if (get_smtp_line() != 250)
  343.     {
  344.       sprintf (str, "The mail server doesn't like the name %s.\nHave you set the 'To: ' field correctly?", ptr);
  345.       smtp_error (str);
  346.       return -1;
  347.     }
  348.  
  349.     if (len == startLen)    // last token, we're done
  350.       break;
  351.   }
  352.  
  353.   sprintf (out_data, "DATA\r\n");
  354.   put_smtp_line (SMTPSock, out_data, strlen (out_data));
  355.  
  356.   if (get_smtp_line() != 354)
  357.   {
  358.     smtp_error ("Mail server error accepting message data");
  359.     return -1;
  360.   }
  361.  
  362.   return(0);
  363.  
  364. }
  365.  
  366. int transform_and_send_edit_data( socktag sock, char * editptr )
  367. {
  368.   char *index;
  369.   char *header_end;
  370.   char previous_char = 'x';
  371.   unsigned int send_len;
  372.   int retval;
  373.   BOOL done = 0;
  374.  
  375.   send_len = lstrlen(editptr);
  376.   index = editptr;
  377.  
  378.   header_end = strstr (editptr, "\r\n\r\n");
  379.  
  380.   while (!done)
  381.   {
  382.     // room for extra char for double dot on end case
  383.     while ((unsigned int) (index - editptr) < send_len)
  384.     {
  385.       switch (*index)
  386.       {
  387.        case '.':
  388.                  if (previous_char == '\n')
  389.                   /* send _two_ dots... */
  390.                   if ((retval = (*pgensock_put_data_buffered) (sock, index, 1))) return (retval);
  391.                    if ((retval = (*pgensock_put_data_buffered) (sock, index, 1))) return (retval);
  392.                  break;
  393.        case '\r':
  394.                  // watch for soft-breaks in the header, and ignore them
  395.                  if (index < header_end && (strncmp (index, "\r\r\n", 3) == 0))
  396.                    index += 2;
  397.                  else
  398.                   if (previous_char != '\r')
  399.                    if ((retval = (*pgensock_put_data_buffered) (sock, index, 1)))
  400.                     return (retval);
  401.                   // soft line-break (see EM_FMTLINES), skip extra CR */
  402.                  break;
  403.        default:
  404.                if ((retval = (*pgensock_put_data_buffered) (sock, index, 1)))
  405.                 return (retval);
  406.       }
  407.       previous_char = *index;
  408.       index++;
  409.     }
  410.     if( (unsigned int) (index - editptr) == send_len) done = 1;
  411.   }
  412.  
  413.   // this handles the case where the user doesn't end the last
  414.   // line with a <return>
  415.  
  416.   if (editptr[send_len-1] != '\n')
  417.   {
  418.     if ((retval = (*pgensock_put_data_buffered) (sock, "\r\n.\r\n", 5)))
  419.       return (retval);
  420.   }
  421.   else
  422.     if ((retval = (*pgensock_put_data_buffered) (sock, ".\r\n", 3)))
  423.       return (retval);
  424.  
  425.   /* now make sure it's all sent... */
  426.   if ((retval = (*pgensock_put_data_flush)(sock))) return (retval);
  427.   return (TRUE);
  428. }
  429.  
  430.  
  431.  
  432. int send_smtp_edit_data (char * message)
  433. {
  434.   transform_and_send_edit_data( SMTPSock, message );
  435.  
  436.   if (get_smtp_line() != 250)
  437.   {
  438.     smtp_error ("Message not accepted by server");
  439.     return -1;
  440.   }
  441.   return(0);
  442. }
  443.  
  444.  
  445. int finish_smtp_message( void )
  446. {
  447.   return put_smtp_line( SMTPSock, "QUIT\r\n", 6 );
  448. }
  449.  
  450. // create a registry entries for this program 
  451. int CreateRegEntry( void )
  452. {
  453.   HKEY  hKey1;
  454.   DWORD  dwDisposition;
  455.   LONG   lRetCode;
  456.  
  457.   /* try to create the .INI file key */
  458.   lRetCode = RegCreateKeyEx ( HKEY_CURRENT_USER,
  459.                               "SOFTWARE\\Public Domain\\Blat",
  460.                               0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,NULL, &hKey1,&dwDisposition
  461.                             );
  462.  
  463.   /* if we failed, note it, and leave */
  464.   if (lRetCode != ERROR_SUCCESS)
  465.   {
  466.     printf ("Error in creating blat key in the registry\n");
  467.     return 10;
  468.   }
  469.  
  470.   /* try to set a section value */
  471.   lRetCode = RegSetValueEx( hKey1,"SMTP server",0,REG_SZ, (BYTE *) &SMTPHost[0], (strlen(SMTPHost)+1));
  472.  
  473.   /* if we failed, note it, and leave */
  474.   if (lRetCode != ERROR_SUCCESS)
  475.   {
  476.     printf ( "Error in setting SMTP server value in the registry\n");
  477.     return 11;
  478.   }
  479.   
  480.   /* try to set another section value */
  481.   lRetCode = RegSetValueEx( hKey1,"Sender",0,REG_SZ, (BYTE *) &Sender[0], (strlen(Sender)+1));
  482.  
  483.   /* if we failed, note it, and leave */
  484.   if (lRetCode != ERROR_SUCCESS)
  485.   {
  486.     printf ( "Error in setting sender address value in the registry\n");
  487.     return 11;
  488.   }
  489.   
  490.   return 0;
  491. }
  492.  
  493. // get the registry entries for this program 
  494. int GetRegEntry( void )
  495. {
  496.   HKEY  hKey1;
  497.   DWORD  dwType;
  498.   DWORD  dwBytesRead;
  499.   LONG   lRetCode;
  500.  
  501.   // open the registry key in read mode
  502.   lRetCode = RegOpenKeyEx( HKEY_CURRENT_USER,
  503.                            "SOFTWARE\\Public Domain\\Blat",
  504.                            0, KEY_READ, &hKey1
  505.                          );
  506.   // set the size of the buffer to contain the data returned from the registry
  507.   // thanks to Beverly Brown "beverly@datacube.com" and "chick@cyberspace.com" for spotting it...
  508.   dwBytesRead=SERVER_SIZE;
  509.   // read the value of the SMTP server entry
  510.   lRetCode = RegQueryValueEx( hKey1, "SMTP server", NULL , &dwType, (BYTE *) &SMTPHost, &dwBytesRead); 
  511.   // if we failed, note it, and leave
  512.   if( lRetCode != ERROR_SUCCESS )
  513.   {
  514.     printf( "Error in reading SMTP server value from the registry\n" );
  515.     return 12;
  516.   }
  517.  
  518.   // read the value of the SMTP server entry
  519.   lRetCode = RegQueryValueEx( hKey1, "Sender", NULL , &dwType, (BYTE *) &Sender, &dwBytesRead); 
  520.   // if we failed, note it, and leave
  521.   if( lRetCode != ERROR_SUCCESS )
  522.   {
  523.     printf( "Error in reading senders user name from the registry\n" );
  524.     return 12;
  525.   }
  526.  
  527.  return 0;
  528. }
  529.  
  530.  
  531. int main( int argc,        /* Number of strings in array argv          */
  532.            char *argv[],    /* Array of command-line argument strings   */
  533.            char **envp )    /* Array of environment variable strings    */
  534. {
  535.     int next_arg=2;
  536.     int impersonating = 0;
  537.     
  538.     // get file name from argv[1]
  539.     char *filename=argv[1];
  540.  
  541.     if(argc<2)
  542.     {
  543.      // must have at least file name to send
  544.      for(int i=0;i<NMLINES;i++) cout<<usage[i]<<'\n';
  545.      return 1;
  546.     }
  547.  
  548.     senderid  = Sender;
  549.     loginname = Sender;
  550.  
  551.       // thanks to Beverly Brown "beverly@datacube.com" for
  552.       // fixing the argument parsing, I "fixed" the brackets
  553.       // to conform approximately to our "style"  :-)
  554.       // Starts here
  555. for(next_arg=1;next_arg < argc;next_arg++)
  556. {
  557.     if(lstrcmpi("-h",argv[next_arg])==0)
  558.     {
  559.      for(int i=0;i<NMLINES;i++) cout<<usage[i]<<'\n';
  560.     return 1;
  561.     }
  562.  
  563.           // is argv[2] "-SMTP"? If so, indicate error and return
  564.     else if(lstrcmpi("-SMTP",argv[next_arg])==0)
  565.     {
  566.        if((argc == 3) || (argc == 4)) 
  567.              {
  568.             strcpy( SMTPHost, argv[++next_arg] );
  569.              if(argc == 4) 
  570.                  strcpy( Sender, argv[++next_arg] );
  571.             else
  572.                 strcpy( Sender, "" );
  573.              if( CreateRegEntry() == 0 ) 
  574.                  {
  575.                   printf("\nSMTP server set to %s\n", SMTPHost );
  576.                  return 0;
  577.                  }
  578.              }
  579.        else
  580.           {
  581.           printf( "to set the SMTP server's address and the user name at that address do:\nblat -SMTP server username");
  582.             return 6;
  583.           }
  584.     }
  585.  
  586.         // is argv[2] "-s"? If so, argv[3] is the subject
  587.     else if(lstrcmpi("-s",argv[next_arg])==0)
  588.     {
  589.     subject=argv[++next_arg];
  590.     }
  591.  
  592.         // is argv[2] "-c"? If so, argv[3] is the carbon-copy list
  593.     else if(lstrcmpi("-c",argv[next_arg])==0)
  594.     {
  595.     cc_list=argv[++next_arg];
  596.     }
  597.  
  598.         // is next argv "-t"? If so, succeeding argv is the destination
  599.     else if(lstrcmpi("-t",argv[next_arg])==0)
  600.     {
  601.     destination=argv[++next_arg];
  602.     }
  603.  
  604.      //is next argv '-f'? If so, succeeding argv is the loginname
  605.     else if(lstrcmp("-f",argv[next_arg])==0)
  606.     {
  607.     loginname=argv[++next_arg];
  608.     if( ! impersonating )
  609.           senderid = loginname;
  610.     }    
  611.  
  612.     //is next argv '-i'? If so, succeeding argv is the sender id
  613.     else if(lstrcmp("-i",argv[next_arg])==0)
  614.     {
  615.     senderid=argv[++next_arg];
  616.     impersonating = 1;
  617.     }
  618.     else if(next_arg == 1) 
  619.     {
  620.     OFSTRUCT of;
  621.         if(lstrlen(filename)<=0 ||
  622.             OpenFile(filename,&of,OF_EXIST)
  623.             ==HFILE_ERROR)
  624.         {
  625.                  cout<<filename<<" does not exist\n";        
  626.                  return 2;
  627.         }
  628.     } 
  629.     else 
  630.     {
  631.     for(int i=0;i<NMLINES;i++)
  632.         cout<<usage[i]<<'\n';
  633.     return 1;
  634.     }
  635. }
  636.       // fixing the argument parsing
  637.       // Ends here
  638.  
  639.      if( GetRegEntry() )
  640.      {
  641.       printf( "to set the SMTP server's address and the user name at that address do:\nblat -SMTP server username\n");
  642.       printf( "aborting, nothing sent\n" );
  643.       return 12;
  644.      }
  645.  
  646.     // make sure filename exists, get full pathname
  647.     OFSTRUCT of;
  648.     if(lstrlen(filename)<=0 || OpenFile(filename,&of,OF_EXIST)==HFILE_ERROR)
  649.     {
  650.      cout<<filename<<" does not exist\n";        
  651.      return 2;
  652.     }
  653.  
  654.     // build the recipients list
  655.     Recipients = new char [ strlen(destination) + strlen(cc_list) + 2 ];
  656.     strcpy( Recipients, destination );
  657.     if( strlen(cc_list) > 0 )
  658.     {
  659.      strcat(Recipients, "," );
  660.      strcat(Recipients, cc_list );
  661.     }
  662.  
  663.     // create a header for the message
  664.     char tmpstr[256];
  665.     char header[1024];
  666.     int  headerlen;
  667.     SYSTEMTIME curtime;
  668.     TIME_ZONE_INFORMATION tzinfo;
  669.     char * days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  670.     char * months[] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  671.     DWORD retval;
  672.  
  673.     GetLocalTime( &curtime );
  674.     retval = GetTimeZoneInformation( &tzinfo );
  675.   
  676.     // rfc1036&rfc822 acceptable format
  677.     // Mon, 29 Jun 94 02:15:23 GMT
  678.     sprintf (tmpstr, "Date: %s, %.2d %s %.2d %.2d:%.2d:%.2d ",
  679.       days[curtime.wDayOfWeek],
  680.       curtime.wDay,
  681.       months[curtime.wMonth - 1],
  682.       curtime.wYear,
  683.       curtime.wHour,
  684.       curtime.wMinute,
  685.       curtime.wSecond);
  686.     strcpy( header, tmpstr );
  687.     for(int i=0;i<32;i++)
  688.     {
  689.      if( retval == TIME_ZONE_ID_STANDARD ) tmpstr[i] = (char) tzinfo.StandardName[i];
  690.      else tmpstr[i] = (char) tzinfo.DaylightName[i];
  691.     }
  692.     strcat( header, tmpstr );
  693.     strcat( header, "\r\n" );
  694.     sprintf( tmpstr, "From: %s\r\n", senderid );
  695.     strcat( header, tmpstr );
  696.     if( impersonating )
  697.     {
  698.      sprintf( tmpstr, "Sender: %s\r\n", loginname );
  699.      strcat( header, tmpstr );
  700.      sprintf( tmpstr, "Reply-to: %s\r\n", loginname );
  701.      strcat( header, tmpstr );
  702.     }
  703.     if( *subject )
  704.     {
  705.      sprintf( tmpstr, "Subject: %s\r\n", subject );
  706.      strcat( header, tmpstr );
  707.     }
  708.     else
  709.     {
  710.      sprintf( tmpstr, "Subject: Contents of file: %s\r\n", filename );
  711.      strcat( header, tmpstr );
  712.     }
  713.     
  714.     sprintf( tmpstr, "To: %s\r\n", destination );
  715.     strcat( header, tmpstr );
  716.     if( *cc_list )
  717.     {
  718.      // Add line for the Carbon Copies
  719.      sprintf( tmpstr, "Cc: %s\r\n", cc_list );
  720.      strcat( header, tmpstr );
  721.     }
  722.     strcat( header, "X-Mailer: <WinNT's Blat ver 1.1>\r\n" );
  723.     strcat( header, "\r\n" );
  724.  
  725.     headerlen = strlen( header );
  726.  
  727.     //get the text of the file into a string buffer
  728.     HANDLE fileh;
  729.     if((fileh=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
  730.                          FILE_FLAG_SEQUENTIAL_SCAN,NULL))==INVALID_HANDLE_VALUE)
  731.     {
  732.      cout<<"error reading "<<filename<<", aborting\n";        
  733.      delete [] Recipients;
  734.      return 3;
  735.     }
  736.     if(GetFileType(fileh)!=FILE_TYPE_DISK)
  737.     {
  738.      cout<<"Sorry, I can only mail messages from disk files...\n";        
  739.      delete [] Recipients;
  740.      return 4;
  741.     }
  742.     DWORD filesize = GetFileSize( fileh,NULL );
  743.     char *buffer = new char[filesize+headerlen+1];
  744.     char *tmpptr;
  745.  
  746.     // put the header at the top...
  747.     strcpy( buffer, header );
  748.     // point to the end of the header
  749.     tmpptr = buffer + headerlen;
  750.     // and put the whole file there
  751.     DWORD dummy;
  752.     if(!ReadFile(fileh,tmpptr,filesize,&dummy,NULL))
  753.     {
  754.      cout<<"error reading "<<filename<<", aborting\n";
  755.      CloseHandle(fileh);
  756.      delete [] buffer;        
  757.      delete [] Recipients;
  758.      return 5;
  759.     }
  760.     CloseHandle(fileh);
  761.         
  762.     cout<<"Sending "<<filename<<" to "<<(lstrlen(Recipients)?
  763.         Recipients:"<unspecified>")<<'\n';
  764.     if(lstrlen(subject))
  765.         cout<<"Subject:"<<subject<<'\n';
  766.     if(lstrlen(loginname))
  767.         cout<<"Login name is "<<loginname<<'\n';
  768.  
  769.   if( !prepare_smtp_message( loginname, Recipients ) )
  770.   {
  771.    if( !send_smtp_edit_data( buffer ) )
  772.     finish_smtp_message();
  773.    close_smtp_socket();
  774.   }
  775.  
  776.   delete [] buffer;
  777.   delete [] Recipients;
  778.   return 0;
  779. }
  780.  
  781.  
  782.  
  783.  
  784.